package com.example.springboot.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.log.Log;
import com.example.springboot.common.Constants;
import com.example.springboot.dto.UserDTO;
import com.example.springboot.entity.Menu;
import com.example.springboot.entity.User;
import com.example.springboot.exception.ServiceException;
import com.example.springboot.mapper.RoleMapper;
import com.example.springboot.mapper.RoleMenuMapper;
import com.example.springboot.mapper.UserMapper;
import com.example.springboot.service.IMenuService;
import com.example.springboot.service.IUserService;
import com.example.springboot.utils.TokenUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author cpf
 *
 */
@Service
public class UserServiceImpl implements IUserService{
    private static final Log LOG = Log.get();

    @Resource
    private UserMapper userMapper;

    @Resource
    private RoleMapper roleMapper;

    @Resource
    private RoleMenuMapper roleMenuMapper;

    @Resource
    private IMenuService menuService;

    @Override
    public UserDTO login(UserDTO userDTO) {
        User one = userMapper.queryByEntity(userDTO);
        if (one != null) {
            User user = new User();
            user.setUserLatestIp(userDTO.getIp());
            user.setUserId(one.getUserId());
            userMapper.update(user);
            BeanUtil.copyProperties(one, userDTO, true);
            // 设置token
            String token = TokenUtils.genToken(one.getId().toString(), one.getPassword());
            userDTO.setToken(token);
            userDTO.setUserName(one.getUserName());

            String role = one.getUserRole(); // ROLE_ADMIN
            // 设置用户的菜单列表
            List<Menu> roleMenus = getRoleMenus(role);
            userDTO.setMenus(roleMenus);
            return userDTO;
        } else {
            throw new ServiceException(Constants.CODE_600, "用户名或密码错误");
        }
    }
    /**
    * 通过ID查询单条数据
    *
    * @param id 主键
    * @return 实例对象
    */
    @Override
    public User queryById(Integer id){
        return this.userMapper.queryById(id);
    }

    /**
    * 条件查询
    * @Param param 查询条件
    */
    @Override
    public List<User>queryAllInfo(Map<String,Object> param){
        return this.userMapper.queryAllInfo(param);
    }
    /**
    * 新增数据
    *
    * @param user 实例对象
    * @return 实例对象
    */
    @Override
    public int insert(User user){
        //加入逻辑代码
        return this.userMapper.insert(user);
    }

    /**
    * 修改数据
    *
    * @param user 实例对象
    * @return 实例对象
    */
    @Override
    public int update(User user){
        //加入逻辑代码
        return this.userMapper.update(user);
    }

    /**
    * 通过主键删除数据
    *
    * @param ids 主键list
    * @return 是否成功
    */
    @Override
    public int deleteByIds(List<Integer> ids){
        return this.userMapper.deleteByIds(ids);
    }

    /**
    *查询结果数
    */
    @Override
    public long count(Map<String,Object> param){
        return this.userMapper.count(param);
    }

    /**
    * 批量插入
    */
    @Override
    public int insertBatch(List<User> entities){
        return this.userMapper.insertBatch(entities);
    }

    /**
     * 获取当前角色的菜单列表
     * @param roleFlag
     * @return
     */
    private List<Menu> getRoleMenus(String roleFlag) {
        Integer roleId = roleMapper.selectByFlag(roleFlag);
        // 当前角色的所有菜单id集合
        List<Integer> menuIds = roleMenuMapper.selectByRoleId(roleId);

        // 查出系统所有的菜单(树形)
        List<Menu> menus = menuService.queryAllInfo(new HashMap<>());
        // new一个最后筛选完成之后的list
        List<Menu> roleMenus = new ArrayList<>();
        // 筛选当前用户角色的菜单
        for (Menu menu : menus) {
            if (menuIds.contains(menu.getId())) {
                roleMenus.add(menu);
            }
            List<Menu> children = menu.getChildren();
            // removeIf()  移除 children 里面不在 menuIds集合中的 元素
            children.removeIf(child -> !menuIds.contains(child.getId()));
        }
        return roleMenus;
    }
}
